package cn.amossun.starter.common.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: Amos.Sun
 * @DateTime: 2020/03/01 14:15
 **/
public class ClassUtil {

    /**
     * 判断是否为: 包装类型&String类型&jdk基础数据类型
     */
    public static boolean isPrimitive(Class<?> clazz) {
        if(clazz == Integer.class || clazz == Long.class
                || clazz == Date.class || clazz == BigDecimal.class
                || clazz == LocalDate.class || clazz == LocalDateTime.class
                || clazz == Boolean.class || clazz == Double.class
                || clazz == Byte.class || clazz == Short.class || clazz == Float.class || clazz == Character.class) {
            return true;
        }
        if (String.class.isAssignableFrom(clazz)) {
            return true;
        } else {
            return clazz.isPrimitive();
        }
    }

    public static List<Field> getClassFields(Class clazz) {
        // 是否是接口
        if (clazz.isInterface()) {
            return null;
        }
        // 判断如果为jdk基本类型，则忽略处理
        if (isPrimitive(clazz)) {
            return null;
        }

        Field[] fields = clazz.getDeclaredFields();
        //排除静态常量
        List<Field> resultFieldList = fields != null && fields.length > 0 ? Arrays.asList(fields) : null;
        if (CollectionUtil.isEmpty(resultFieldList)) {
            return null;
        }
        return resultFieldList.stream()
                .filter(source-> !Modifier.isStatic(source.getModifiers())) //排除静态
                .filter(source-> !Modifier.isFinal(source.getModifiers())) //排除常量
                .collect(Collectors.toList());
    }

    public static List<Field> getAllClassFields(Class clazz) {
        // 判断如果为基础类型，则忽略处理
        if (isPrimitive(clazz)) {
            return null;
        }
        // 是否是接口
        if (clazz.isInterface()) {
            return null;
        }
        List<Field> resultFieldList = new ArrayList<>(clazz.getDeclaredFields().length * 2);
        Class currentClass = clazz;
        while (currentClass != null) {
            List<Field> classFiledList = getClassFields(currentClass);
            if(CollectionUtil.isNotEmpty(classFiledList)) {
                resultFieldList.addAll(classFiledList);
            }
            currentClass = currentClass.getSuperclass();
        }
        return resultFieldList;
    }

}
